package com.srs.backend.serviceImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mysql.cj.xdevapi.Table;
import com.srs.backend.consumer.WebSocketServer;
import com.srs.backend.mapper.*;
import com.srs.backend.pojo.*;
import com.srs.backend.service.OrderService;
import com.srs.backend.utils.Result;
import io.jsonwebtoken.io.IOException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OrderItemMapper orderItemMapper;
    @Resource
    private ServerMapper serverMapper;
    @Resource
    private MaterialMapper materialMapper;
    @Resource
    private FoodMaterialMapper foodMaterialMapper;
    @Resource
    private ClientMapper clientMapper;
    @Resource
    private TableMapper tableMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private FoodMapper foodMapper;

    @Override
    public Result add(Map<String, String> data){
        String clientIdStr = data.get("client_id");
        Integer clientId;
        String clientNumStr = data.get("client_num");
        Integer clientNum;
        String tableIdStr = data.get("table_id");
        Integer tableId;
        String statusStr = data.get("status");
        Integer status;
        String serverIdStr = data.get("server_id");
        Integer serverId;
        String remark = data.get("remark");

        try {
            clientId = Integer.parseInt(clientIdStr);
            clientNum = Integer.parseInt(clientNumStr);
            tableId = Integer.parseInt(tableIdStr);
            status = Integer.parseInt(statusStr);
            serverId = Integer.parseInt(serverIdStr);
        } catch (NumberFormatException e) {
            return Result.error("数据类型错误");
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            String createTimeStr = null;
            Date createTime = dateFormat.parse(createTimeStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            String finishiTimeStr = null;
            Date finishiTime = dateFormat1.parse(finishiTimeStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Date createTime = new Date();
        Date finishTime = new Date();

        orderMapper.insert(new Orders(null, clientId, clientNum, tableId, status, serverId, createTime ,finishTime , remark, null, null, null));

        return Result.ok("success");

    }

    @Override
    public Result delete(Map<String, String> data) {
        String idStr = data.get("id");
        Integer id = null;
        try {
            id = Integer.parseInt(idStr);
        } catch (NumberFormatException e) {
            return Result.error("id数据有误");
        }
        Orders curOrder = orderMapper.selectById(id);
        if (curOrder == null) {
            return Result.error("当前订单不存在或已被删除");
        }
        orderMapper.deleteById(curOrder);


        QueryWrapper<OrderItem> orderItemQueryWrapper = new QueryWrapper<>();
        orderItemQueryWrapper.eq("order_id", id);
        List<OrderItem> orderItems = orderItemMapper.selectList(orderItemQueryWrapper);

        for (int i = 0; i < orderItems.size(); i ++ ) {
            orderItemMapper.deleteById(orderItems.get(i));
        }

        return Result.ok("success");
    }

    @Override
    public Result modify(Map<String, String> data) {
        String idStr = data.get("id");
        Integer id = null;
        try {
            id = Integer.parseInt(idStr);
        } catch (NumberFormatException e) {
            return Result.error("id数据有误");
        }
        Orders curOrder = orderMapper.selectById(id);
        if (curOrder == null) {
            return Result.error("当前操作菜单不存在或已被删除");
        }

        String clientIdStr = data.get("client_id");
        Integer clientId;
        String clientNumStr = data.get("client_num");
        Integer clientNum;
        String tableIdStr = data.get("table_id");
        Integer tableId;
        String statusStr = data.get("status");
        Integer status;
        String serverIdStr = data.get("server_id");
        Integer serverId;
        String createTimeStr = data.get("create_time");
        Date createTime = null;
        String finishTimeStr = data.get("finish_time");
        Date finishTime = null;
        String remark = data.get("remark");

        try {
            clientId = Integer.parseInt(clientIdStr);
            clientNum = Integer.parseInt(clientNumStr);
            tableId = Integer.parseInt(tableIdStr);
            status = Integer.parseInt(statusStr);
            serverId = Integer.parseInt(serverIdStr);
        } catch (NumberFormatException e) {
            return Result.error("数据类型错误");
        }

        curOrder.setClientId(clientId);
        curOrder.setClientNum(clientNum);
        curOrder.setTableId(tableId);
        curOrder.setStatus(status);
        curOrder.setServerId(serverId);
        curOrder.setCreateTime(createTime);
        curOrder.setFinishTime(finishTime);
        curOrder.setRemark(remark);

        orderMapper.updateById(curOrder);
        return Result.ok("success");
    }

    @Override
    public Result getAll() {
        return null;
    }

    // 添加订单并添加对应的OrderItem项，并修改原材料的数量
    @Override
    public Result addOrderAndItems(Map<String, Object> data) {
        List<Food> foodList;
        try {
            if(data.get("food_list") instanceof ArrayList){
                foodList = (ArrayList<Food>)data.get("food_list");
            } else {
                return Result.error("菜品数据有误");
            }
        } catch (Exception e) {
            return Result.error("菜品数据有误");
        }

        if (foodList.isEmpty()) {
            return Result.error("菜品数据有误");
        }

        Integer clientId;
        Integer clientNum;
        Integer tableId;
        String remark = (String) data.get("remark");

        try {
            clientId = (Integer) data.get("client_id");
            clientNum = (Integer) data.get("client_num");
            tableId = (Integer) data.get("table_id");
        } catch (NumberFormatException e) {
            return Result.error("数据类型错误");
        }

        if (tableId <= 0) {
            return Result.error("请选择用餐桌子");
        }

        String isPredetermineStr = (String) data.get("is_predetermine");
        String predetermineTimeStr = (String) data.get("predetermine_time");
        Date predetermineTime = null;
        Integer isPredetermine;
        try {
            isPredetermine = Integer.parseInt(isPredetermineStr);
        } catch (Exception e) {
            return Result.error("是否预定类型错误");
        }

        if (isPredetermine.equals(1)) {
            try {
                SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                predetermineTime = ft.parse(predetermineTimeStr);
            } catch (Exception e) {
                return Result.error("预定时间格式错误");
            }
        }

        // 判断client_id是否合法
        Client client1 = clientMapper.selectById(clientId);
        if (client1 == null) {
            return  Result.error("顾客id非法");
        }

        // 判断桌子id是否合法
        Tables table1 = tableMapper.selectById(tableId);
        if (table1 == null) {
            return Result.error("桌子id非法");
        }
        if (table1.getStatus() != 0 && isPredetermine == 0) {
            return Result.error("桌子正在使用中，请选择其他桌子");
        }
        // todo 预定桌子合法性判断

        // 判断client_num是否合法
        if (clientNum <= 0 || clientNum > 20) {
            return Result.error("顾客数量范围有误");
        }

        List<Food> foods = new LinkedList<>();
        // food_list 不能直接遍历，否则会报错
        // 需要json转换
        // 遍历food_list
        for(Object object:foodList){
            // 将list中的数据转成json字符串
            String jsonObject = JSON.toJSONString(object);
            //将json转成需要的对象
            Food food = JSONObject.parseObject(jsonObject,Food.class);
            foods.add(food);
        }

        if (foods.size() == 0) {
            return Result.error("您还没有选择任何食物，请挑选菜品后再提交吧！");
        }

        // 核查原材料是否支持该订单
        // 先查
        // Map<material_id, num>
        Map<Integer, Integer> map = new HashMap<>();
        for (Food food : foods) {
            QueryWrapper<FoodMaterial> foodMaterialQueryWrapper = new QueryWrapper<>();
            foodMaterialQueryWrapper.eq("food_id", food.getId());
            List<FoodMaterial> foodMaterialList = foodMaterialMapper.selectList(foodMaterialQueryWrapper);
            for (FoodMaterial foodMaterial : foodMaterialList) {
                Integer curNum = map.get(foodMaterial.getMaterialId());
                if (curNum == null) {
                    map.put(foodMaterial.getMaterialId(), foodMaterial.getMaterialNum());
                } else {
                    map.put(foodMaterial.getMaterialId(), foodMaterial.getMaterialNum() + curNum);
                }
            }
        }

        // 再比较
        boolean flag = true;
        Material m = null;
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            Material curMaterial = materialMapper.selectById(entry.getKey());
            if (curMaterial.getNum() < entry.getValue()) {
                flag = false;
                m = curMaterial;
                break;
            }
        }

        // 最后改变库存
        if (flag) {
            for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
                Material curMaterial = materialMapper.selectById(entry.getKey());
                curMaterial.setNum(curMaterial.getNum() - entry.getValue());
                materialMapper.updateById(curMaterial);
            }
        } else {
            return Result.error(m.getName() + "原材料库存不足");
        }

        Date t = new Date();

        List<OrderItem> orderItemList = new LinkedList<>();
        Orders curOrders;

        Orders order = new Orders(null, clientId, clientNum, tableId, 0, 0, t ,null ,remark, null, isPredetermine,  predetermineTime);
        orderMapper.insert(order);
        curOrders = order;


        for (int i = 0; i < foods.size(); i ++ ) {
            Food food = foods.get(i);
            for (int j = 0; j < food.getNum(); j ++ ) {
                OrderItem tmp = new OrderItem(null, order.getId(), food.getId(), null, null, new Date(), null);
                orderItemMapper.insert(tmp);
                orderItemList.add(tmp);
            }
        }

        System.out.println(curOrders);
        System.out.println(orderItemList);

        if (isPredetermine == 0) {
            List<Integer> userIdList = WebSocketServer.getUserIdList();
            for (Integer uid : userIdList) {
                User curUser = userMapper.selectById(uid);
                try {
                    if (curUser.getIdKind() == 1) {
                        WebSocketServer.sendInfo(uid, Result.ok("111", curOrders));
                    } else if (curUser.getIdKind() == 2) {
                        WebSocketServer.sendInfo(uid, Result.ok("222", orderItemList));
                    }
                } catch (java.io.IOException e) {
                    System.out.println("websocket error");
                }
            }
        }

        return Result.ok();
    }

    // 获取用户的订单
    @Override
    public Result getAllByClientId(Map<String, String> data) {
        String clientIdStr = data.get("client_id");
        Integer clientId;
        try {
            clientId = Integer.parseInt(clientIdStr);
        } catch (Exception e) {
            return  Result.error("client_id数据类型有误");
        }
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("client_id", clientId);
        List<Orders> ordersList = orderMapper.selectList(queryWrapper);

        return Result.ok(ordersList);
    }

    // 获取一段时间内的总销售额
    @Override
    public Result getTotalMoneyByPeriod(Map<String, String> data) {
        String startTimeStr = data.get("start_time");
        String endTimeStr = data.get("end_time");
        Date startTime, endTime;
        try {
            SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            startTime = ft.parse(startTimeStr);
            endTime = ft.parse(endTimeStr);
        } catch (ParseException e) {
            return Result.error("日期格式有误");
        }

        Double res = 0.0;

//        System.out.println(startTime);
//        System.out.println(endTime);

        List<Orders> orders = orderMapper.selectList(null);
        for (Orders item:
                orders) {
            if (item.getFinishTime() != null) {
//                System.out.println(item.getFinishTime());
                if (item.getFinishTime().before(endTime) && item.getFinishTime().after(startTime)) {
                    res += item.getTotalMoney();
                }
            }
        }

//        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
//        queryWrapper.ge("finish_time", startTime);
//        queryWrapper.le("finish_time", endTime);
//        List<Orders> ordersList = orderMapper.selectList(queryWrapper);


//        Double res = 0.0;
//        for (int i = 0; i < ordersList.size(); i ++ ) {
//            res += ordersList.get(i).getTotalMoney();
//        }

        return Result.ok(res);
    }

    // 确认收款
    @Override
    public Result checkOut(Map<String, String> data) {
        System.out.println(data);
        String serverIdStr = data.get("server_id");
        String totalMoneyStr = data.get("total_money");
        String orderIdStr = data.get("order_id");

        Integer serverId;
        Double totalMoney;
        Integer orderId;
        try {
            serverId = Integer.parseInt(serverIdStr);
            totalMoney = Double.parseDouble(totalMoneyStr);
            orderId = Integer.parseInt(orderIdStr);
        } catch (Exception e) {
            return Result.error("数据类型有误");
        }
        Orders curorders = orderMapper.selectById(orderId);
        if (curorders == null) {
            return Result.error("当前账单不存在或已被删除");
        }
        Server curServer = serverMapper.selectById(serverId);
        if (curServer == null) {
            return Result.error("当前服务员不存在或已被删除");
        }
        if (totalMoney < 0 || totalMoney > 100000000) {
            return  Result.error("结账款项数据有误");
        }

        curorders.setServerId(serverId);
        curorders.setTotalMoney(totalMoney);
        curorders.setStatus(1);
        curorders.setFinishTime(new Date());

        Integer table_id = curorders.getTableId();
        Tables table = tableMapper.selectById(table_id);
        table.setStatus(1);
        tableMapper.updateById(table);

        orderMapper.updateById(curorders);

        return Result.ok();
    }

    @Override
    public Result getAllUnpaidOrders() {
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 0);
        List<Orders> res = orderMapper.selectList(queryWrapper);
        for (int i = 0; i < res.size(); i ++ ) {
            res.get(i).setSum(this.getOrderSum(res.get(i).getId()));
        }
        return Result.ok(res);
    }

    public Double getOrderSum(Integer id) {
        Double res = 0.0;

        QueryWrapper<OrderItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", id);
        List<OrderItem> orderItems = orderItemMapper.selectList(queryWrapper);

        for (OrderItem orderitem:
                orderItems) {
            res += foodMapper.selectById(orderitem.getFoodId()).getPrice();
        }

        return res;
    }
}
